home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / impacket / ntlm.py < prev    next >
Text File  |  2006-05-23  |  9KB  |  260 lines

  1. # Copyright (c) 2003-2006 CORE Security Technologies
  2. #
  3. # This software is provided under under a slightly modified version
  4. # of the Apache Software License. See the accompanying LICENSE file
  5. # for more information.
  6. #
  7. # $Id: ntlm.py,v 1.2 2006/05/23 21:19:25 gera Exp $
  8. #
  9.  
  10. from impacket.structure import Structure
  11. try:
  12.     from Crypto.Cipher import DES
  13.     from Crypto.Hash import MD4
  14.     POW = None
  15. except Exception:
  16.     try:
  17.         import POW
  18.     except Exception:
  19.         pass
  20.  
  21. NTLM_AUTH_NONE          = 1
  22. NTLM_AUTH_CONNECT       = 2
  23. NTLM_AUTH_CALL          = 3
  24. NTLM_AUTH_PKT           = 4
  25. NTLM_AUTH_PKT_INTEGRITY = 5
  26. NTLM_AUTH_PKT_PRIVACY   = 6
  27.  
  28. NTLMSSP_KEY_56       = 0x80000000
  29. NTLMSSP_KEY_EXCHANGE = 0x40000000
  30. NTLMSSP_KEY_128      = 0x20000000
  31. # NTLMSSP_           = 0x10000000
  32. # NTLMSSP_           = 0x08000000
  33. # NTLMSSP_           = 0x04000000
  34. # NTLMSSP_           = 0x02000000
  35. # NTLMSSP_           = 0x01000000
  36. NTLMSSP_TARGET_INFO  = 0x00800000
  37. # NTLMSSP_           = 0x00400000
  38. # NTLMSSP_           = 0x00200000
  39. # NTLMSSP_           = 0x00100000
  40. NTLMSSP_NTLM2_KEY    = 0x00080000
  41. NTLMSSP_CHALL_NOT_NT = 0x00040000
  42. NTLMSSP_CHALL_ACCEPT = 0x00020000
  43. NTLMSSP_CHALL_INIT   = 0x00010000
  44. NTLMSSP_ALWAYS_SIGN  = 0x00008000       # forces the other end to sign packets
  45. NTLMSSP_LOCAL_CALL   = 0x00004000
  46. NTLMSSP_WORKSTATION  = 0x00002000
  47. NTLMSSP_DOMAIN       = 0x00001000
  48. # NTLMSSP_           = 0x00000800
  49. # NTLMSSP_           = 0x00000400
  50. NTLMSSP_NTLM_KEY     = 0x00000200
  51. NTLMSSP_NETWARE      = 0x00000100
  52. NTLMSSP_LM_KEY       = 0x00000080
  53. NTLMSSP_DATAGRAM     = 0x00000040
  54. NTLMSSP_SEAL         = 0x00000020
  55. NTLMSSP_SIGN         = 0x00000010       # means packet is signed, if verifier is wrong it fails
  56. # NTLMSSP_           = 0x00000008
  57. NTLMSSP_TARGET       = 0x00000004
  58. NTLMSSP_OEM          = 0x00000002
  59. NTLMSSP_UNICODE      = 0x00000001
  60.  
  61. class NTLMAuthHeader(Structure):
  62.     commonHdr = (
  63.         ('auth_type', 'B=10'),
  64.         ('auth_level','B'),
  65.         ('auth_pad_len','B=0'),
  66.         ('auth_rsvrd','"\x00'),
  67.         ('auth_ctx_id','<L=747920'),
  68.         )
  69.     structure = (
  70.         ('data',':'),
  71.     )
  72.                                                                                 
  73. class NTLMAuthNegotiate(NTLMAuthHeader):
  74.     structure = (
  75.         ('','"NTLMSSP\x00'),
  76.         ('message_type','<L=1'),
  77.         ('flags','<L'),
  78.         ('domain_len','<H-domain_name'),
  79.         ('domain_max_len','<H-domain_name'),
  80.         ('domain_offset','<L'),
  81.         ('host_len','<H-host_name'),
  82.         ('host_maxlen','<H-host_name'),
  83.         ('host_offset','<L'),
  84.         ('host_name',':'),
  85.         ('domain_name',':'))
  86.                                                                                 
  87.     def __init__(self):
  88.         NTLMAuthHeader.__init__(self)
  89.         self['flags']= (
  90.                NTLMSSP_KEY_128     |
  91.                NTLMSSP_KEY_EXCHANGE|
  92.                # NTLMSSP_LM_KEY      |
  93.                NTLMSSP_NTLM_KEY    |
  94.                NTLMSSP_UNICODE     |
  95.                # NTLMSSP_ALWAYS_SIGN |
  96.                NTLMSSP_SIGN        |
  97.                NTLMSSP_SEAL        |
  98.                # NTLMSSP_TARGET      |
  99.                0)
  100.         self['host_name']=''
  101.         self['domain_name']=''
  102.     
  103.     def __str__(self):
  104.         self['host_offset']=32
  105.         self['domain_offset']=32+len(self['host_name'])
  106.         return NTLMAuthHeader.__str__(self)
  107.  
  108. class NTLMAuthChallenge(NTLMAuthHeader):
  109.     structure = (
  110.         ('','"NTLMSSP\x00'),
  111.         ('message_type','<L=2'),
  112.         ('domain_len','<H-domain_name'),
  113.         ('domain_max_len','<H-domain_name'),
  114.         ('domain_offset','<L'),
  115.         ('flags','<L'),
  116.         ('challenge','8s'),
  117.         ('reserved','"\x00\x00\x00\x00\x00\x00\x00\x00'),
  118.         ('domain_name',':'))
  119.                                                                                 
  120. class NTLMAuthChallengeResponse(NTLMAuthHeader):
  121.     structure = (
  122.         ('','"NTLMSSP\x00'),
  123.         ('message_type','<L=3'),
  124.         ('lanman_len','<H-lanman'),
  125.         ('lanman_max_len','<H-lanman'),
  126.         ('lanman_offset','<L'),
  127.         ('ntlm_len','<H-ntlm'),
  128.         ('ntlm_max_len','<H-ntlm'),
  129.         ('ntlm_offset','<L'),
  130.         ('domain_len','<H-domain_name'),
  131.         ('domain_max_len','<H-domain_name'),
  132.         ('domain_offset','<L'),
  133.         ('user_len','<H-user_name'),
  134.         ('user_max_len','<H-user_name'),
  135.         ('user_offset','<L'),
  136.         ('host_len','<H-host_name'),
  137.         ('host_max_len','<H-host_name'),
  138.         ('host_offset','<L'),
  139.         ('session_key_len','<H-session_key'),
  140.         ('session_key_max_len','<H-session_key'),
  141.         ('session_key_offset','<L'),
  142.         ('flags','<L'),
  143.         ('domain_name',':'),
  144.         ('user_name',':'),
  145.         ('host_name',':'),
  146.         ('lanman',':'),
  147.         ('ntlm',':'),
  148.         ('session_key',':'))
  149.  
  150.     def __init__(self, username, password, challenge):
  151.         NTLMAuthHeader.__init__(self)
  152.         self['session_key']=''
  153.         self['user_name']=username.encode('utf-16le')
  154.         self['domain_name']='' #"CLON".encode('utf-16le')
  155.         self['host_name']='' #"BETS".encode('utf-16le')
  156.         self['flags'] = (   #authResp['flags']
  157.                 # we think (beto & gera) that his flags force a memory conten leakage when a windows 2000 answers using uninitializaed verifiers
  158.            NTLMSSP_KEY_128     |
  159.            NTLMSSP_KEY_EXCHANGE|
  160.            # NTLMSSP_LM_KEY      |
  161.            NTLMSSP_NTLM_KEY    |
  162.            NTLMSSP_UNICODE     |
  163.            # NTLMSSP_ALWAYS_SIGN |
  164.            NTLMSSP_SIGN        |
  165.            NTLMSSP_SEAL        |
  166.            # NTLMSSP_TARGET      |
  167.            0)
  168.         # Here we do the stuff
  169.         if username and password:
  170.             lmhash = compute_lmhash(password)
  171.             nthash = compute_nthash(password)
  172.             self['lanman']=get_ntlmv1_response(lmhash, challenge)
  173.             self['ntlm']=get_ntlmv1_response(nthash, challenge)    # This is not used for LM_KEY nor NTLM_KEY
  174.         else:
  175.             self['lanman'] = ''
  176.             self['ntlm'] = ''
  177.             if not self['host_name']:
  178.                 self['host_name'] = 'NULL'.encode('utf-16le')      # for NULL session there must be a hostname
  179.                                                                                 
  180.     def __str__(self):
  181.         self['domain_offset']=64
  182.         self['user_offset']=64+len(self['domain_name'])
  183.         self['host_offset']=self['user_offset']+len(self['user_name'])
  184.         self['lanman_offset']=self['host_offset']+len(self['host_name'])
  185.         self['ntlm_offset']=self['lanman_offset']+len(self['lanman'])
  186.         self['session_key_offset']=self['ntlm_offset']+len(self['ntlm'])
  187.         return NTLMAuthHeader.__str__(self)
  188.                                                                                 
  189. class ImpacketStructure(Structure):
  190.     def set_parent(self, other):
  191.         self.parent = other
  192.  
  193.     def get_packet(self):
  194.         return str(self)
  195.  
  196.     def get_size(self):
  197.         return len(self)
  198.  
  199. class NTLMAuthVerifier(NTLMAuthHeader):
  200.     structure = (
  201.         ('version','<L=1'),
  202.         ('data','12s'),
  203.         # ('_zero','<L=0'),
  204.         # ('crc','<L=0'),
  205.         # ('sequence','<L=0'),
  206.     )
  207.  
  208. KNOWN_DES_INPUT = "KGS!@#$%"
  209.  
  210. def __expand_DES_key( key):
  211.     # Expand the key from a 7-byte password key into a 8-byte DES key
  212.     key  = key[:7]
  213.     key += '\x00'*(7-len(key))
  214.     s = chr(((ord(key[0]) >> 1) & 0x7f) << 1)
  215.     s = s + chr(((ord(key[0]) & 0x01) << 6 | ((ord(key[1]) >> 2) & 0x3f)) << 1)
  216.     s = s + chr(((ord(key[1]) & 0x03) << 5 | ((ord(key[2]) >> 3) & 0x1f)) << 1)
  217.     s = s + chr(((ord(key[2]) & 0x07) << 4 | ((ord(key[3]) >> 4) & 0x0f)) << 1)
  218.     s = s + chr(((ord(key[3]) & 0x0f) << 3 | ((ord(key[4]) >> 5) & 0x07)) << 1)
  219.     s = s + chr(((ord(key[4]) & 0x1f) << 2 | ((ord(key[5]) >> 6) & 0x03)) << 1)
  220.     s = s + chr(((ord(key[5]) & 0x3f) << 1 | ((ord(key[6]) >> 7) & 0x01)) << 1)
  221.     s = s + chr((ord(key[6]) & 0x7f) << 1)
  222.     return s
  223.  
  224. def __DES_block(key, msg):
  225.     if POW:
  226.         cipher = POW.Symmetric(POW.DES_ECB)
  227.         cipher.encryptInit(__expand_DES_key(key))
  228.         return cipher.update(msg)
  229.     else:
  230.         cipher = DES.new(__expand_DES_key(key),DES.MODE_ECB)
  231.         return cipher.encrypt(msg)
  232.  
  233. def ntlmssp_DES_encrypt(key, challenge):
  234.     answer  = __DES_block(key[:7], challenge)
  235.     answer += __DES_block(key[7:14], challenge)
  236.     answer += __DES_block(key[14:], challenge)
  237.     return answer
  238.  
  239. def compute_lmhash(password):
  240.     # This is done according to Samba's encryption specification (docs/html/ENCRYPTION.html)
  241.     password = password.upper()
  242.     lmhash  = __DES_block(password[:7], KNOWN_DES_INPUT)
  243.     lmhash += __DES_block(password[7:14], KNOWN_DES_INPUT)
  244.     return lmhash
  245.  
  246. def compute_nthash(password):
  247.     # This is done according to Samba's encryption specification (docs/html/ENCRYPTION.html)
  248.     password = unicode(password).encode('utf_16le')
  249.     if POW:
  250.         hash = POW.Digest(POW.MD4_DIGEST)
  251.     else:        
  252.         hash = MD4.new()
  253.     hash.update(password)
  254.     return hash.digest()
  255.  
  256. def get_ntlmv1_response(key, challenge):
  257.     return ntlmssp_DES_encrypt(key, challenge)
  258.  
  259.  
  260.